package cc.siyecao.fastdfs.command.tracker;


import cc.siyecao.fastdfs.model.RecvPackageInfo;
import cc.siyecao.fastdfs.model.StorageInfo;
import cc.siyecao.fastdfs.protocol.ProtocolConstants;
import cc.siyecao.fastdfs.util.BytesUtil;
import cc.siyecao.fastdfs.util.ProtocolUtil;

import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.util.Arrays;

/**
 * 获取存储节点命令
 *
 * @author lyt
 */
public class GetStoreStorageCommand extends FdfsTrackerCommand<StorageInfo> {
    public GetStoreStorageCommand() {

    }

    public GetStoreStorageCommand(String groupName) {
        this.groupName = groupName;
    }

    @Override
    protected void send(OutputStream out, Charset charset) throws Exception {
        byte[] header;
        byte cmd;
        int outLen;
        if (groupName == null || groupName.length() == 0) {
            cmd = TRACKER_PROTO_CMD_SERVICE_QUERY_STORE_WITHOUT_GROUP_ONE;
            outLen = 0;
        } else {
            cmd = TRACKER_PROTO_CMD_SERVICE_QUERY_STORE_WITH_GROUP_ONE;
            outLen = ProtocolConstants.FDFS_GROUP_NAME_MAX_LEN;
        }
        header = ProtocolUtil.packHeader( cmd, outLen, (byte) 0 );
        out.write( header );

        if (groupName != null && groupName.length() > 0) {
            byte[] bGroupName;
            byte[] bs;
            int groupLen;

            bs = groupName.getBytes( charset );
            bGroupName = new byte[ProtocolConstants.FDFS_GROUP_NAME_MAX_LEN];

            if (bs.length <= ProtocolConstants.FDFS_GROUP_NAME_MAX_LEN) {
                groupLen = bs.length;
            } else {
                groupLen = ProtocolConstants.FDFS_GROUP_NAME_MAX_LEN;
            }
            Arrays.fill( bGroupName, (byte) 0 );
            System.arraycopy( bs, 0, bGroupName, 0, groupLen );
            out.write( bGroupName );
        }
    }

    @Override
    protected StorageInfo receive(InputStream in, Charset charset) throws Exception {
        RecvPackageInfo pkgInfo = ProtocolUtil.recvPackage( in, TRACKER_PROTO_CMD_RESP, ProtocolConstants.TRACKER_QUERY_STORAGE_STORE_BODY_LEN );
        this.errno = pkgInfo.errno;
        if (pkgInfo.errno != 0) {
            return null;
        }
        String ipAddr = new String( pkgInfo.body, ProtocolConstants.FDFS_GROUP_NAME_MAX_LEN, ProtocolConstants.FDFS_IPADDR_SIZE - 1 ).trim();
        int port = (int) BytesUtil.buff2long( pkgInfo.body, ProtocolConstants.FDFS_GROUP_NAME_MAX_LEN + ProtocolConstants.FDFS_IPADDR_SIZE - 1 );
        byte storePath = pkgInfo.body[ProtocolConstants.TRACKER_QUERY_STORAGE_STORE_BODY_LEN - 1];

        return new StorageInfo( ipAddr, port, storePath );
    }
}
